package com.gujiangbo.threadpool;

import java.util.LinkedList;

/**
 * 任务队列设计
 */
public class LinkedRunnableQueue implements RunnableQueue {

    // 最大容量
    private final int limit;
    // 拒绝策略
    private final DenyPolicy denyPolicy;
    //存放任务的队列
    private final LinkedList<Runnable> runnableList = new LinkedList<>();

    private final ThreadPool threadPool;

    public LinkedRunnableQueue(int limit, DenyPolicy denyPolicy, ThreadPool threadPool) {
        this.limit = limit;
        this.denyPolicy = denyPolicy;
        this.threadPool = threadPool;
    }

    @Override
    public void offer(Runnable runnable) {
        synchronized (runnableList) {
            //当队列中的任务超过最大值，触发拒绝策略
            if (runnableList.size() >= limit) {
                denyPolicy.reject(runnable, threadPool);
            } else {
                //否则加入到队列中
                runnableList.addLast(runnable);
                runnableList.notifyAll();
            }
        }

    }


    @Override
    public Runnable take() throws InterruptedException {
        synchronized (runnableList) {
            while (runnableList.isEmpty()) {
                try {
                    //如果任务队列中没有可执行的任务，则当前线程将会挂起，
                    // 进入runnableList关联的monitor waitset中等待唤醒
                    runnableList.wait();
                } catch (InterruptedException e) {
                    throw e;
                }
            }
            //从队列中取出第一位元素
            return runnableList.removeFirst();
        }
    }

    @Override
    public int size() {
        synchronized (runnableList) {
            //获取队列大小
            return runnableList.size();
        }
    }
}
